package uni.edu.pe.analisisSentimental.service.impl;

import java.util.Date;
import java.util.List;

import org.apache.commons.lang.builder.ToStringBuilder;
import org.apache.commons.lang.builder.ToStringStyle;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import twitter4j.Query;
import twitter4j.QueryResult;
import twitter4j.Status;
import twitter4j.Twitter;
import twitter4j.TwitterException;
import twitter4j.TwitterFactory;
import uni.edu.pe.analisisSentimental.dao.TweetManagerDAO;
import uni.edu.pe.analisisSentimental.domain.TweetBean;
import uni.edu.pe.analisisSentimental.service.TweetManagerService;

/**
 * Clase de servicio que provee los metodos correspondientes a las
 * reasignaciones
 * 
 * @author naudante
 * 
 */
@Service
public class TweetManagerServiceImpl implements TweetManagerService
{
 
    private static Logger logger = LoggerFactory.getLogger(TweetManagerServiceImpl.class);

    @Autowired TweetManagerDAO tweetManagerDAO;

    public static final String QUERY_EXPRESIONES_NEGATIVAS = ":(";
    public static final String QUERY_EXPRESIONES_POSITIVAS = ":)";
    private static final String LENGUAJE_CONSULTA_ESPANOL = "es";
    private static final int NRO_MAXIMO_REGISTROS_POR_PAGINA = 100;
    private static final int NRO_TOTAL_PAGINAS = 15;
    
    public static final String OPINION_POLARIDAD_POSITIVA = "P";
    public static final String OPINION_POLARIDAD_NEGATIVA = "N";
    private static final String OPINION_OBJETIVA = "O";

    
    /*
     * (non-Javadoc)
     * @see uni.edu.pe.analisisSentimental.service.TweetManagerService#recuperarTweets()
     */
	public void recuperarTweets() {
		logger.debug("<==== Inicio Method recuperarTweets a las "+new Date()+" ====>");	
		
    	logger.debug("recibiendo todos los tweets :(");
    	List<Status> tweets = armaQueyEnBaseAConsulta(QUERY_EXPRESIONES_NEGATIVAS, OPINION_POLARIDAD_NEGATIVA);
    	persistirTweet(tweets, QUERY_EXPRESIONES_NEGATIVAS, OPINION_POLARIDAD_NEGATIVA);
    	tweets = null;
    	
    	logger.debug("recibiendo todos los tweets :)");
    	tweets = armaQueyEnBaseAConsulta(QUERY_EXPRESIONES_POSITIVAS, OPINION_POLARIDAD_POSITIVA);
    	persistirTweet(tweets, QUERY_EXPRESIONES_POSITIVAS, OPINION_POLARIDAD_POSITIVA);
	}
	
	
	/**
	 * Metodo que permite crear la consulta en tweeter
	 * en base al texto ingresado en el query.
	 * @param textoConsultaEjecutar
	 * @return 
	 */
    public List<Status> armaQueyEnBaseAConsulta(String textoConsultaEjecutar, String polaridadIndicada)
    {
        logger.info("<====  armaQueyEnBaseAConsulta ====>");
        //Twitter twitter = new TwitterFactory().getInstance();
        Twitter twitter = TwitterFactory.getSingleton();
        Query query = new Query(textoConsultaEjecutar);
        
        //TODO: Revisar como se maneja el paginado aca
        //query.setRpp(NRO_MAXIMO_REGISTROS_POR_PAGINA);     
       
        query.setLang(LENGUAJE_CONSULTA_ESPANOL); 
        return ejecutaQueryEnTwitter(twitter, query, polaridadIndicada);
        
        
    }

    /**
     * Metodo que permite ejecutar la sentencia
     * de consulta a tweeter
     * @param twitter
     * @param query
     * @param polaridadIndicada 
     */
	private List<Status>  ejecutaQueryEnTwitter(Twitter twitter, Query query, String polaridadIndicada) {
		logger.debug("<====  Inicio Method ejecutaQueryEnTwitter ====>");
		List<Status> tweets = null;
		try {
		
            QueryResult result = twitter.search(query);
            logger.debug("Count : " + result.getTweets().size()) ;
            
            tweets = result.getTweets();
            
        } catch (TwitterException e) {
            logger.error("Error al procesar la consulta a tweeter: ",e);
        }
        return tweets;
	}
	
	private void persistirTweet(List<Status> tweets, String query, String polaridadIndicada){
		logger.debug("<====  Inicio Method persistirTweet ====>");
		TweetBean tweetDto = null;
		 for (Status tweet : tweets) {
             logger.debug("tweet completo: {}", ToStringBuilder.reflectionToString(tweet, ToStringStyle.MULTI_LINE_STYLE));
         	tweetDto = new TweetBean();
         	tweetDto.setId(tweet.getId());
         	tweetDto.setMensaje_original(tweet.getText());
         	//tweetDto.setUsuario_origen(tweet.getFromUser());
         	tweetDto.setUsuario_origen(tweet.getUser().getName());
         	//tweetDto.setUsuario_destino(tweet.getToUser());
         	tweetDto.setUsuario_destino(tweet.getUser().getName());
         	tweetDto.setFecha_creacion(tweet.getCreatedAt());
         	tweetDto.setPolaridad_asumida(polaridadIndicada);
         	tweetDto.setQuery(query);
         	tweetDto.setLenguaje_tweet(LENGUAJE_CONSULTA_ESPANOL);
         	persistirTweet(tweetDto);

         }
	}
	/**
	 * Metodo que se encarga de registrar los tweets en la base de datos.
	 * Dado que la llave primaria es el id del tweet, va a haber circunstancias
	 * en que se quiera registrar un tweet registrado con anterioridad, en cuyo caso
	 * solo se ignorara la excepcion, esto para evitar hacer el chequeo de existencia de twwets
	 * en cada oportunidad.
	 * @param tweetBean
	 */
	private void persistirTweet(TweetBean tweetBean)
	{
		logger.debug("<====  Inicio Method persistirTweets ====>");
		try{
			if(logger.isDebugEnabled()){
				//ToStringBuilder.reflectionToString(tweetBean, ToStringStyle.MULTI_LINE_STYLE);
				logger.debug("tweet completo: {}",ToStringBuilder.reflectionToString(tweetBean));
			}
			int count = 0;
			count =	tweetManagerDAO.obtenerContadorEntradasDelTweetEnBD(tweetBean.getId());
			if(count == 0){
				tweetManagerDAO.insertTweet(tweetBean);
			}else
			{
				logger.warn("El tweet con id: {}, ya se encontraba registrado: ", tweetBean.getId());
			}
		}
		catch(Exception e)
		{
			logger.error("Error al grabar el tweet: ",e);
		}	
	}

	public void grabarTweets(TweetBean tweetBean) {
		logger.debug("<====  Inicio Method grabarTweets ====>");
		tweetBean.setId(5000L);
		tweetBean.setFecha_creacion(new Date());
		tweetBean.setMensaje_original("Mensaje Dummy Original de Prueba");
		tweetBean.setMensaje_procesado("Mensaje Dummy Procesado de Prueba");
		tweetBean.setPolaridad_asumida("2");
		tweetBean.setQuery("query de prueba");
		tweetBean.setUsuario_destino("@usuarioOrigen");
		tweetBean.setUsuario_origen("@usuarioOrigen");
		//tweetManagerDAO.persist(tweetBean);
		tweetManagerDAO.insertTweet(tweetBean);
	}

  
}